﻿using System.Text.RegularExpressions;

namespace OnWork.DataCenter.Utils
{
    /// <summary>
    /// 字符串格式化 占位符
    /// </summary>
    public static class StringFormat
    {
        /// <summary>
        /// 测试模板替换，vs2017->鼠标方法名->右键交互执行->需要把那些依赖的方法和using都交互执行过才行
        /// </summary>
        public static void Test()
        {
            SafeMap<object> map = new SafeMap<object>();
            map["username"] = "wagsn";
            map["password"] = "123456";

            Console.WriteLine(ReplacePlaceholder("${username}: ${password}", map));
            // 输出结果为：wagsn: 123456
        }

        /// <summary>
        /// 占位符替换: ${TagName} -> TagValue
        /// 例："${year}-${month}-${day}" -> "2018-11-28"
        /// </summary>
        /// <param name="template">模板字符串</param>
        /// <returns>替换后的字符串</returns>
        public static string ReplacePlaceholder<TValue>(string template, SafeMap<TValue> pairs)
        {
            string result = new string(template.ToCharArray());

            if (pairs != null)
            {
                // TODO 需要优化为，匹配到 \$\{(\S*?)\} 后按照匹配到的内容作为Key在Map中寻找Value替换
                foreach (var key in pairs.Keys)
                {
                    Regex regex = new Regex(@"\$\{" + key + @"\}");
                    result = regex.Replace(result, pairs[key].ToString());
                }
            }
            return result;
        }

        /// <summary>
        /// 安全的映射表，不存在的Key返回默认的Value，string类型将返回string.Empty（""）
        /// </summary>
        public class SafeMap<TValue>
        {
            /// <summary>
            /// 获取Keys
            /// </summary>
            public IEnumerable<string> Keys
            {
                get
                {
                    return kvs.Keys;
                }
            }

            private Dictionary<string, TValue> kvs = new Dictionary<string, TValue>();

            /// <summary>
            /// 索引器
            /// </summary>
            /// <param name="index">索引</param>
            /// <returns>值</returns>
            public TValue this[string index]
            {
                get
                {
                    return Get(index);
                }
                set
                {
                    Set(index, value);
                }
            }

            /// <summary>
            /// 获取Key对应的值
            /// </summary>
            /// <param name="index">索引</param>
            /// <returns>值</returns>
            public TValue? Get(string index)
            {
                if (kvs.ContainsKey(index))
                {
                    return kvs[index];
                }
                else
                {
                    return default;
                }
            }

            /// <summary>
            /// 设置Key对应的值
            /// </summary>
            /// <param name="index">索引</param>
            /// <param name="value">值</param>
            public void Set(string index, TValue value)
            {
                kvs[index] = value;
            }
        }
    }
}